package codename.primavera.model;

import java.util.Collection;
import java.util.HashSet;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;


/**
 * The Class User.
 */
@Entity
public class User implements UserDetails {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The user name. */
    @Id
    @Column(name = "USER_ID")
    @Size(min = 3, max = 10)
    private String username;

    /** The password. */
    @NotNull
    @Size(min = 6, max = 40)
    @Column(name = "PASSWORD")
    private String password;

    /** The name. */
    @Column(name = "NAME")
    private String name;

    /** The first name. */
    @Column(name = "FIRSTNAME")
    private String firstName;

    /** The enabled. */
    @Column(name = "B_ENABLED")
    private Boolean enabled;

    /** The credentials expired. */
    @Column(name = "B_CREDENTIALSEXPIRED")
    private Boolean credentialsExpired;

    /** The account locked. */
    @Column(name = "B_LOCKED")
    private Boolean accountLocked;

    /** The account expired. */
    @Column(name = "B_EXPIRED")
    private Boolean accountExpired;

    /** The identifier. */
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Role role;
    
    /**
     * Gets the username.
     *
     * @return the username
     * {@inheritDoc}
     */
    @Override
    public String getUsername() {
        return username;
    }

    /**
     * Sets the user name.
     *
     * @param username the new username
     */
    public void setUsername(final String username) {
        this.username = username;
    }

    /**
     * Gets the password.
     * @return the password
     */
    @Override
    public String getPassword() {
        return password;
    }

    /**
     * Sets the password.
     * @param password the new password
     */
    public void setPassword(final String password) {
        this.password = password;
    }

    /**
     * Gets the authorities.
     *
     * @return the authorities
     * {@inheritDoc}
     */
    @Override
    public Collection < GrantedAuthority > getAuthorities() {
        final Collection < GrantedAuthority > authz = new HashSet < GrantedAuthority >();
        authz.add(role);
        return authz;
    }

    /**
     * Checks if is account non expired.
     *
     * @return true, if is account non expired
     * {@inheritDoc}
     */
    @Override
    public boolean isAccountNonExpired() {
        return BooleanUtils.isNotTrue(accountExpired);
    }

    /**
     * Checks if is account non locked.
     *
     * @return true, if is account non locked
     * {@inheritDoc}
     */
    @Override
    public boolean isAccountNonLocked() {
        return BooleanUtils.isNotTrue(accountLocked);
    }

    /**
     * Checks if is credentials non expired.
     *
     * @return true, if is credentials non expired
     * {@inheritDoc}
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return BooleanUtils.isNotTrue(credentialsExpired);
    }

    /**
     * Checks if is enabled.
     *
     * @return true, if is enabled
     * {@inheritDoc}
     */
    @Override
    public boolean isEnabled() {
        return BooleanUtils.isNotFalse(enabled);
    }

    /**
     * Gets the name.
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the name.
     * @param name the new name
     */
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Gets the first name.
     * @return the first name
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * Sets the first name.
     * @param firstName the new first name
     */
    public void setFirstName(final String firstName) {
        this.firstName = firstName;
    }

    /**
     * Sets the enabled.
     * @param enabled the new enabled
     */
    public void setEnabled(final Boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * Sets the credentials expired.
     * @param credentialsExpired the new credentials expired
     */
    public void setCredentialsExpired(final Boolean credentialsExpired) {
        this.credentialsExpired = credentialsExpired;
    }

    /**
     * Sets the account locked.
     * @param accountLocked the new account locked
     */
    public void setAccountLocked(final Boolean accountLocked) {
        this.accountLocked = accountLocked;
    }

    /**
     * Sets the account expired.
     * @param accountExpired the new account expired
     */
    public void setAccountExpired(final Boolean accountExpired) {
        this.accountExpired = accountExpired;
    }

    
    
    /**
     * Gets the role.
     *
     * @return the role
     */
    public Role getRole() {
        return role;
    }

    /**
     * Sets the role.
     *
     * @param role the new role
     */
    public void setRole(Role role) {
        this.role = role;
    }

    /**
     * Gets the enabled.
     *
     * @return the enabled
     */
    public Boolean getEnabled() {
        return enabled;
    }

    /**
     * Gets the credentials expired.
     *
     * @return the credentials expired
     */
    public Boolean getCredentialsExpired() {
        return credentialsExpired;
    }

    /**
     * Gets the account locked.
     *
     * @return the account locked
     */
    public Boolean getAccountLocked() {
        return accountLocked;
    }

    /**
     * Gets the account expired.
     *
     * @return the account expired
     */
    public Boolean getAccountExpired() {
        return accountExpired;
    }

    /**
     * Hash code.
     *
     * @return the int
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(getUsername()).toHashCode();
    }

    /**
     * Equals.
     *
     * @param obj the obj
     * @return true, if successful
     * {@inheritDoc}
     */
    @Override
    public boolean equals(final Object obj) {
        if (null == obj)
            return false;
        if (this == obj)
            return true;
        if (!(obj instanceof User))
            return false;
        final User that = (User) obj;
        return new EqualsBuilder().append(getUsername(), that.getUsername()).isEquals();

    }
    
    /**
     * To string.
     *
     * @return the string
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("username",getUsername()).append("rights", getAuthorities()).toString();
    }

}
